package com.ly.houses.job;

import com.ly.houses.common.OssService;
import com.ly.houses.model.Building;
import com.ly.houses.model.Plate;
import com.ly.houses.service.BuildingService;
import com.ly.houses.service.HouseService;
import com.ly.houses.service.HousesMailService;
import com.ly.houses.service.PlateService;
import com.ly.houses.thread.UpdateHouseDetail;
import org.apache.commons.lang3.StringUtils;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.io.IOException;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

@Component
public class CcUtil {
    @Resource
    private PlateService plateService;
    @Resource
    private BuildingService buildingService;
    @Resource
    private HouseService houseService;
    @Resource
    private OssService ossService;
    @Resource
    private HousesMailService housesMailService;

    /**
     *
     * @return 每天4点执行
     * @throws Exception
     */
    @Scheduled(cron = "0 0 4 * * ?")
    public String houses() throws Exception {
        List<Plate> plates = new ArrayList<>();
        //从贝壳获取房屋列表
        String initUrl = "https://cc.fang.ke.com/loupan/nhs1pg1/";
        Document document = Jsoup.connect(initUrl).get();
        String maxNum = document.select(".page-box").get(0).attr("data-total-count");
        BigDecimal pages = BigDecimal.valueOf(Long.parseLong(maxNum)).divide(BigDecimal.valueOf(10), 0, BigDecimal.ROUND_UP);
        //处理分页查询
        for (int i = 1; i <= Integer.valueOf(String.valueOf(pages)); i++) {
            String url = "https://cc.fang.ke.com/loupan/nhs1pg" + i + "/";
            Document pageDucument = Jsoup.connect(url).get();
            Elements Ul = pageDucument.select(".resblock-list-wrapper");
            Elements Lis = Ul.select(".resblock-list");
            //获取到房屋div
            for (Element element : Lis) {
                Plate plate = new Plate();
                String lpName = element.getElementsByClass("resblock-name").get(0).select("a").get(0).text();
                String lpAddress = element.getElementsByClass("resblock-location").get(0).ownText();

                Elements lpUnitTypes = element.getElementsByClass("resblock-room").get(0).select("span");
                String area = "";
                String unitType = "";
                if (lpUnitTypes.size() > 2) {
                    String[] unitTypes = new String[lpUnitTypes.size() - 2];
                    for (int j = 1; j < lpUnitTypes.size() - 1; j++) {
                        unitTypes[j - 1] = lpUnitTypes.get(j).text();
                    }
                    area = lpUnitTypes.get(lpUnitTypes.size() - 1).text().split("建面")[1];
                    unitType = StringUtils.join(unitTypes, ",");
                }

                String src = element.getElementsByClass("lj-lazy").get(0).attr("data-original");
                //图片临时地址
                plate.setImgSrc(src);
                //楼盘名称
                plate.setName(lpName);
                //楼盘地址
                plate.setAddress(lpAddress);
                //楼盘属性
                plate.setUnitType(unitType);
                //楼盘建面
                plate.setArea(area);
                //放到楼盘列表中
                plates.add(plate);
            }
        }
        //通过名称查询当地房产局信息
        getPublicIdByName(plates);
        //查询楼盘信息
        getPlateByPublicId();
        //查询楼栋信息
        getbuildingByPlate();
        //查询房屋信息
        getHouseByBuildingThread();
        //均价
        getAvgPrice();
        return "ok";
    }

    /**
     * 通过名称获取当地房产局官方publicId
     * @param plates
     * @throws Exception
     */
    private void getPublicIdByName(List<Plate> plates) throws Exception {
        List<String> plateNames = plateService.selectAllPlaceName(1L);
        //新增集合
        List<Plate> insertPlates = new ArrayList<>();
        List<String> publicIds = new ArrayList<>();
        for (Plate plate : plates) {
            String xmmc = URLEncoder.encode(URLEncoder.encode(plate.getName()));
            String imgurl = "http://www.ccfdw.net/ecdomain/ccfcjwz/wsba/zslp/search.jsp?xmmc=" + xmmc + "&type=1";
            Document initDocument = Jsoup.connect(imgurl).get();
            Elements tableElements = initDocument.select("table");
            if (tableElements.size() >= 2) {
                Element tableElement = tableElements.get(1);
                Elements tbodyElements = tableElement.select("tbody");
                for (int i = 0; i < tbodyElements.size(); i++) {
                    Element tbodyElement = tbodyElements.get(0);
                    Elements trElements = tbodyElement.select("tr");
                    //存在多页的情况
                    if (trElements.size() == 11) {

                        Elements as = trElements.get(10).select("a");
                        for (int l = 0; l < as.size() - 2; l++) {
                            //获取楼盘信息
                            String url = "http://ccfdw.net/ecdomain/ccfcjwz/wsba/zslp/search.jsp?xmmc=" + xmmc + "&type=1&nowPage=" + l + 1;
                            Document pageDocument = Jsoup.connect(url).get();
                            Elements pageTableElements = pageDocument.select("table");
                            if (pageTableElements.size() >= 2) {
                                Element pageTableElement = pageTableElements.get(1);
                                Elements pageTbodyElements = pageTableElement.select("tbody");
                                for (int o = 0; o < pageTbodyElements.size(); o++) {
                                    Element pageTbodyElement = pageTbodyElements.get(0);
                                    Elements pageTrElements = pageTbodyElement.select("tr");
                                    for (int p = 1; l < pageTrElements.size() - 1; p++) {
                                        Elements pageTdElements = pageTrElements.get(p).select("td").get(0).select("a");
                                        if (pageTdElements != null && pageTdElements.size() > 0) {
                                            if (pageTdElements.get(0) != null && !pageTdElements.get(0).equals("")) {
                                                if ("返回网站首页".equals(pageTdElements.get(0).text())) {
                                                    //处理错误查询
                                                    continue;
                                                }
                                                String publicId = pageTdElements.get(0).attr("onclick").split(",")[0].split("'")[1];
                                                if (publicIds.contains(publicId)) {
                                                    //防止重复添加
                                                    continue;
                                                }

                                                publicIds.add(publicId);
                                                if (plateNames.contains(pageTdElements.get(0).text())) {
                                                    plateNames.remove(pageTdElements.get(0).text());
                                                    //防止重复入库
                                                    continue;
                                                }


                                                if (plate.getName().equals(pageTdElements.get(0).text())) {
                                                    //如果名称相同则使用带来的图
                                                    plate.setPublicId(publicId);
                                                    String imgAddress = ossService.uploadUrl(plate.getImgSrc().split(".592x432")[0]);
                                                    plate.setImgId(imgAddress);
                                                    plate.setImgAddress("https://cchouse.oss-cn-beijing.aliyuncs.com/" + imgAddress + "?x-oss-process=image/resize,m_lfit,h_90,w_160");
                                                    plate.setAreaId(1L);
                                                    insertPlates.add(plate);
                                                } else {
                                                    //如果没有使用默认图
                                                    Plate newPlate = new Plate();
                                                    newPlate.setImgAddress("https://cchouse.oss-cn-beijing.aliyuncs.com/default-cover.png");

                                                    newPlate.setPublicId(publicId);
                                                    newPlate.setName(pageTdElements.get(0).text());
                                                    newPlate.setAreaId(1L);
                                                    insertPlates.add(newPlate);
                                                }
                                            }
                                        }
                                    }
                                }

                            }
                        }
                    } else {
                        for (int l = 1; l < trElements.size() - 1; l++) {
                            Elements tdElements = trElements.get(l).select("td").get(0).select("a");
//                            Elements tdElements = trElements.get(l).select("td").get(0).select("a");
                            if (tdElements != null && tdElements.size() > 0) {
                                if (tdElements.get(0) != null && !tdElements.get(0).equals("")) {
                                    if ("返回网站首页".equals(tdElements.get(0).text())) {

                                        continue;
                                    }
                                    String publicId = tdElements.get(0).attr("onclick").split(",")[0].split("'")[1];
                                    if (publicIds.contains(publicId)) {
                                        continue;
                                    }

                                    publicIds.add(publicId);
                                    if (plateNames.contains(tdElements.get(0).text())) {
                                        plateNames.remove(tdElements.get(0).text());
                                        continue;
                                    }
                                    if (plate.getName().equals(tdElements.get(0).text())) {
                                        plate.setPublicId(publicId);
                                        String imgAddress = ossService.uploadUrl(plate.getImgSrc().split(".592x432")[0]);
                                        plate.setImgId(imgAddress);
                                        plate.setImgAddress("https://cchouse.oss-cn-beijing.aliyuncs.com/" + imgAddress + "?x-oss-process=image/resize,m_lfit,h_90,w_160");
                                        plate.setAreaId(1L);
                                        insertPlates.add(plate);
                                    } else {
                                        Plate newPlate = new Plate();
                                        newPlate.setImgAddress("https://cchouse.oss-cn-beijing.aliyuncs.com/default-cover.png");
                                        newPlate.setPublicId(publicId);
                                        newPlate.setName(tdElements.get(0).text());
                                        newPlate.setAreaId(1L);
                                        insertPlates.add(newPlate);
                                    }
                                }
                            }
                        }
                    }
                }

            }
        }
        //如果有新增的入库
        if (insertPlates.size() > 0) {
            plateService.batchSave(insertPlates);
        }
        //如果本次查询不在的，删除数据库数据
        if (plateNames.size() > 0) {
            plateService.removePlacesByName(plateNames, 1L);
        }
    }

    /**
     * 通过publicId获取楼盘内容
     *
     * @throws IOException
     */
    private void getPlateByPublicId() throws IOException {
        List<Plate> plates = plateService.selectAllPlace(1L);
        List<Plate> updatePlates = new ArrayList<>();

        for (Plate plate : plates) {
            if (plate.getPublicId() != null) {
                String plateMsgUrl = "http://www.ccfdw.net/ecdomain/lpcs/xmxx/xmjbxxinfo.jsp?Id_xmxq=" + plate.getPublicId();
                Document initDocument = Jsoup.connect(plateMsgUrl).get();
                Elements trElements = initDocument.getElementById("content1").select("table").get(1).select("tbody").get(0).select("tr");
                //地址
                String address = trElements.get(0).select("td").get(1).text();
                //开盘时间
                String beginTime = trElements.get(1).select("td").get(1).text();
                //绿化率
                String greeningRate = trElements.get(2).select("td").get(3).text();
                //开发商
                String developer = trElements.get(3).select("td").get(1).text();
                plate.setAddress(address);
                plate.setBeginTime(beginTime);
                plate.setGreeningRate(greeningRate);
                plate.setDeveloper(developer);
                updatePlates.add(plate);
            }
        }
        //批量修改
        if (updatePlates.size() > 0) {
            plateService.batchUpdate(updatePlates);
        }
    }

    /**
     * 通过楼盘主键获取楼栋信息
     *
     * @throws IOException
     */
    private void getbuildingByPlate() throws IOException {
        List<Plate> plates = plateService.selectAllPlace(1L);
        List<Building> buildings = new ArrayList<>();

        for (Plate plate : plates) {
            if (plate.getPublicId() != null) {
                List<Building> isBuildings = buildingService.listBuildingByPlateId(plate.getId());
                String buildsUrl = "http://www.ccfdw.net/ecdomain/lpcs/xmxx/loulist.jsp?Id_xmxq=" + plate.getPublicId();
                Document initDocument = Jsoup.connect(buildsUrl).get();
                Elements divElements = initDocument.getElementById("content").select("div").get(0).select("div");
                for (int i = 0; i < divElements.size(); i++) {
                    if (i > 0) {
                        Building building = new Building();
                        String buildingName = divElements.get(i).select("strong").get(0).text();
                        String buildingPublicId = divElements.get(i).select("a").get(0).attr("onClick").split("'")[1];
                        boolean isHas = false;
                        for (Building isBuilding : isBuildings) {
                            if (buildingPublicId.equals(isBuilding.getPublicId())) {
                                isHas = true;
                                break;
                            }
                        }
                        if (!isHas) {
                            building.setPublicId(buildingPublicId);
                            building.setName(buildingName);
                            building.setPlateId(plate.getId());
                            String buildingUrl = "http://www.ccfdw.net/ecdomain/lpcs/xmxx/lpbxx_new.jsp?lid=" + building.getPublicId();

                            Document buildingDocument;
                            try {
                                buildingDocument = Jsoup.connect(buildingUrl).get();


                                Elements trElements = buildingDocument.getElementById("content1").select("tbody").get(0).select("tr");
                                //期房/现房
                                String buildingType = trElements.get(1).select("td").get(3).text();
                                //房屋用途
                                String useFor = trElements.get(2).select("td").get(1).text();
                                //地上层数
                                String floorNum = trElements.get(2).select("td").get(3).text();
                                //地下层数
                                String underFloorNum = trElements.get(2).select("td").get(5).text();
                                //总套数
                                String allNum = trElements.get(3).select("td").get(1).text();
                                //总建筑面积
                                String area = trElements.get(3).select("td").get(3).text();
                                //住宅总套数
                                String roomAllNum = trElements.get(3).select("td").get(5).text();
                                //住宅总建筑面积
                                String roomArea = trElements.get(4).select("td").get(1).text();
                                //共有公用分摊面积
                                String publicArea = trElements.get(4).select("td").get(3).text();
                                //楼栋区号
                                String areaCode = trElements.get(4).select("td").get(5).text();
                                //楼栋街路号
                                String roadCode = trElements.get(5).select("td").get(1).text();
                                //楼栋丘地号
                                String landCode = trElements.get(5).select("td").get(3).text();
                                //楼栋栋号
                                String buildingCode = trElements.get(5).select("td").get(5).text();
                                building.setBuildingType(buildingType);
                                building.setUseFor(useFor);
                                building.setFloorNum(floorNum);
                                building.setUnderFloorNum(underFloorNum);
                                building.setAllNum(allNum);
                                building.setArea(area);
                                building.setRoomAllNum(roomAllNum);
                                building.setRoomArea(roomArea);
                                building.setPublicArea(publicArea);
                                building.setAreaCode(areaCode);
                                building.setRoadCode(roadCode);
                                building.setLandCode(landCode);
                                building.setBuildingCode(buildingCode);
                                buildings.add(building);
                            } catch (Exception e) {
                                //防止出现查不到的情况，先放过
                                continue;
                            }
                        }

                    }

                }
            }
        }
        if (buildings.size() > 0) {
            try {
                //批量新增
                buildingService.batchSave(buildings);
            } catch (Exception e) {
                //todo 还没处理批量新增数据量大而失败的问题
                housesMailService.sendSimpleMailMessage("楼栋批量新增失败");
//                buildingService.batchSave(buildings);
            }

        }
    }

    /**
     * 通过楼栋获取房间信息
     */
    private void getHouseByBuildingThread() {


        List<Building> buildings = buildingService.selectAllBuilding();
        CountDownLatch latch = new CountDownLatch(buildings.size());
        //创建一个缓冲池
        ExecutorService pool = Executors.newCachedThreadPool();
        //设置其容量为7 根据自己电脑cpu核数自己设定，一般核心数+1
        pool = Executors.newFixedThreadPool(7);

        for (Building building : buildings) {
            pool.execute(new UpdateHouseDetail(latch, building, houseService, housesMailService));
        }
        try {
            latch.await();

        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    /**
     * 获取均价
     */
    public void getAvgPrice() {
        List<Plate> plates = plateService.listPlateByName(null, 1L);
        for (Plate plate : plates) {
            plate.setAvgPrice(plateService.getAvgPrice(plate.getId()));
        }
        if (plates.size() > 0) {
            plateService.updateAvgPrice(plates);
        }
    }

}
